<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo</title>
    <style>
        body {
            margin: 0;
        }

        .masonry {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-gap: 0 60px;
            grid-auto-rows: 2px;
            /* 通过grid-auto-rows: 2px将每一行的网格设置为 2px 高度 */
            align-items: end;
        }

        .item {
            background: #ccc;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        @media (min-width: 1280px) and (max-width: 1920px) {
            .masonry {
                grid-template-columns: repeat(3, 1fr);
            }
        }

        @media (min-width: 768px) and (max-width: 1280px) {
            .masonry {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        @media (max-width: 768px) {
            .masonry {
                grid-template-columns: repeat(1, 1fr);
            }
        }
    </style>
</head>

<body>
    <div class="masonry">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
        <div class="item">item5</div>
        <div class="item">item6</div>
        <div class="item">item7</div>
        <div class="item">item8</div>
        <div class="item">item9</div>
        <div class="item">item10</div>
        <div class="item">item11</div>
        <div class="item">item12</div>
        <div class="item">item13</div>
        <div class="item">item14</div>
        <div class="item">item15</div>
        <div class="item">item16</div>
        <div class="item">item17</div>
        <div class="item">item18</div>
        <div class="item">item19</div>
        <div class="item">item20</div>
        <div class="item">item21</div>
        <div class="item">item22</div>
        <div class="item">item23</div>
        <div class="item">item24</div>
        <div class="item">item25</div>
    </div>

    <script>
        // 给每个元素模拟随机高度
        window.addEventListener('load', () => {
            document.querySelectorAll('.masonry > .item').forEach(item => {
                item.style.height = `${Math.floor(Math.random() * 200) + 100}px`
            })
        })

        const calcRows = () => {
            const masonry = document.querySelector('.masonry')
            const items = masonry.querySelectorAll('.item')
            // 获取当前列数
            const cols = getComputedStyle(masonry).gridTemplateColumns.split(" ").length;
            items.forEach((item, index) => {
                // 给需要上下间隔的元素增加上间隔（每列第一个元素无需上间隔）
                const gapRows = index >= cols ? 8 : 0;
                // 根据元素高度设置元素的需占行数
                const rows = Math.ceil(item.clientHeight / 2) + gapRows;
                item.style.gridRowEnd = `span ${rows}`;
            })
        }

        window.addEventListener('resize', calcRows)
        window.addEventListener('load', calcRows)
    </script>
</body>

</html>